<?php

abstract class FormComponent extends AbstractRenderable
{

  /**
   * @var int
   */
  public $add = Form::ACTION_ALL;

  /**
   * @var int
   */
  public $remove = Form::ACTION_NONE;

  /**
   * @var Form
   */
  public $form;

  /**
   * @var string
   */
  public $name;

  /**
   * @var string
   */
  public $title;

  /**
   *
   * @var mixed
   */
  protected $layout = false;

  /**
   * @var FilterChain
   */
  protected $filterChain;

  /**
   * Constructor.
   *
   * @param string $name the element's name
   * @param string $title the element's title
   * @return void
   */
  public function __construct($name, $title = null)
  {
    $this->name = $name;
    $this->title = $title;
  }

  /**
   *
   * @return string the element's name
   */
  public function getName()
  {
    return $this->name;
  }

  /**
   *
   * @return string the element's title
   */
  public function getTitle()
  {
    if (is_null($this->title)) {
      $this->title = Inflector::titleize($this->getName());
    }

    return $this->title;
  }

  /**
   *
   * @return FilterChain
   */
  public function filters($hook = null)
  {
    if (empty($this->filterChain)) {
      $this->filterChain = new FilterChain();
    }

    if (func_num_args()) {
      return call_user_func_array(array($this->filterChain, 'call'), func_get_args());
    }

    return $this->filterChain;
  }

  /**
   *
   * @return boolean
   */
  public function show($action)
  {
    return ($this->add & $action & ~$this->remove) == $action;
  }

  public function validate($row)
  {
  }

  public function beforeRender($row, $action)
  {
    $this->filters('before_render', $row, $action);
  }

  public function render($row, $action)
  {
    return $this->getView()->render();
  }

  public function afterRender(&$output, $row, $action)
  {
    return $this->filters('after_render', $output, $row, $action);
  }

  public function injectQueryParams(&$params)
  {
  }

  public function filterDbData(&$row, $action)
  {
  }

  public function executeCallback($callback)
  {
    $func = array($this, $callback);

    if (method_exists($func[0], $func[1])) {
      $args = func_get_args();
      unset($args[0]);
      call_user_func_array($func, $args);
    }
  }

}
